package boot.spring.model.response;

import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;

import java.io.Serializable;

@Data
public class Response<T> implements Serializable {
    /**
     * 返回值为0或1，1表示请求失败；0表示请求成功。
     */
    private Integer status;
    /**
     * 返回状态说明，当status为1时，info会返回具体错误原因，否则返回‘OK’。
     */
    private String info;
    /**
     * 返回的数据结果对象
     */
    private T result;
    /**
     * 时间戳
     */
    @JsonIgnore
    private Long timestamp;

    public Response() {
    }

    private Response(Integer code, String message, T result) {
        this.status = code;
        this.info = null == message ? "" : message;
        this.result = result;
        this.timestamp = System.currentTimeMillis();
    }

    public Response(final Integer code, final String msg, final T result, final Long timestamp) {
        this.status = code;
        this.info = null == msg ? "" : msg;
        this.result = result;
        this.timestamp = timestamp;
    }

    public static <T> Response<T> success() {
        return new Response(0, null, null);
    }

    public static <T> Response<T> success(T data) {
        return new Response(0, null, data);
    }

    public static <T> Response<T> success(String message) {
        return new Response(0, message, null);
    }

    public static <T> Response<T> success(String message, T data) {
        return new Response(0, message, data);
    }

    public static <T> Response<T> success(Integer code, String message, T data) {
        return new Response(code, message, data);
    }

    public static <T> Response<T> error(T data) {
        return fail(data);
    }

    public static <T> Response<T> error() {
        return fail();
    }

    public static <T> Response<T> error(String message) {
        return fail(message);
    }

    public static <T> Response<T> error(Integer code, String message, T data) {
        return fail(code, message, data);
    }

    public static <T> Response<T> fail(T data) {
        return new Response(1, null, data);
    }

    public static <T> Response<T> fail() {
        return new Response(1, null, null);
    }

    public static <T> Response<T> fail(String message) {
        return new Response(1, message, null);
    }

    public static <T> Response<T> fail(Integer code, String message, T data) {
        return new Response(code, message, data);
    }
}
